package com.allen.app.common.config.swagger.common;

import cn.hutool.core.util.StrUtil;
import com.allen.app.common.utils.Jackson;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import springfox.documentation.schema.ModelProperty;

/**
 * @author xiaojian  created in  2020/1/16 10:14
 */
public class ModelPropertyUtil {

    /**
     *  更改枚举字段描述
     * @param val
     * @param erasedType
     * @return
     */
    public static ModelProperty enumModelProperty(ModelProperty val, Class<?> erasedType){
        List<Map<String, Object>> enumValues = ModelPropertyUtil.getEnumValues(erasedType);
        ModelProperty modelProperty = new ModelProperty(
                val.getName(),
                val.getType(),
                val.getQualifiedType(),
                val.getPosition(),
                val.isRequired(),
                val.isHidden(),
                val.isReadOnly(),
                val.isAllowEmptyValue(),
                Jackson.json(enumValues),
                val.getAllowableValues(),
                val.getExample(),
                val.getPattern(),
                val.getDefaultValue(),
                val.getXml(),
                val.getVendorExtensions()
        );
        modelProperty.updateModelRef((resolvedType) -> val.getModelRef());
        return modelProperty;
    }


    /**
     * 获取枚举所有值的属性
     *
     * @param clazz
     * @return
     */
    public static  <T> List<Map<String, Object>> getEnumValues(Class<T> clazz) {
        Objects.requireNonNull(clazz);
        if (!clazz.isEnum()) {
            return null;
        }


        // 获取 枚举的属性字段 和 get方法
        Map<String, String> propData = new HashMap<String, String>();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.getModifiers() == 2 || field.getModifiers() == 18) {
                propData.put(field.getName(), "get".concat(StrUtil.upperFirst(field.getName())));
            }
        }

        // 生成map value
        List<Map<String, Object>> dataList = new ArrayList<>();
        T[] objs = clazz.getEnumConstants();
        for (int i = 0; i < objs.length; i++) {
            Map<String, Object> data = new HashMap<String, Object>();
            //data.put("ordinal", i);
            data.put("name", objs[i].toString());
            for (Map.Entry<String, String> entry : propData.entrySet()) {
                try {
                    Method method = clazz.getMethod(entry.getValue());
                    data.put(entry.getKey(), method.invoke(objs[i]));
                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
                        | SecurityException e) {
                    e.printStackTrace();
                }
            }
            dataList.add(data);
        }

        return dataList;
    }

}
